import store from '../state/modules/auth.js';
//生成唯一标识符
function getUuid() {
	const s = [];
	const hexDigits = '0123456789abcdef';
	for (let i = 0; i < 36; i++) {
		s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	}
	s[14] = '4';
	s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
	s[8] = s[13] = s[18] = s[23] = '-';
	return s.join('');
}

class socketClient {
	// 是否主动关闭
	isClose = false;
	wsUUID = '';
	wsUrl = '';
	websocket = null;
	// ws 心跳对象
	heartCheck = {
		// 收到心跳回复后再次发送心跳的间隔时间;也是ws连接不上的最大等待时间 之后关掉连接并重连
		timeout: 10000,
		timeoutObj: null,
		serverTimeoutObj: null,
		reset: function() {
			clearTimeout(this.timeoutObj || '');
			clearTimeout(this.serverTimeoutObj || '');
			return this;
		},
		start: function(SocketTask) {
			this.timeoutObj = setTimeout(() => {
				SocketTask.send({
					data: 'heartbeat',
				});
				this.serverTimeoutObj = setTimeout(() => {
					SocketTask.close();
				}, this.timeout);
			}, this.timeout);
		},
	};
	reconnectObj = {
		timeout: 5000, // 重连间隔时间
		timer: null, // 重连计时器
		lock: false, // 重连锁
		limit: 0, // 重连次数
		maxLimit: 99999, // 重连最大次数
	};

	constructor(wsUrl) {
		this.wsUrl = wsUrl;
	}

	// 初始化socket  status 是否是重连
	initWebSocket(status = false) {
		this.websocket = uni.connectSocket({
			url: this.wsUrl,
			success: () => {
				// 创建成功 生成唯一标识符
				this.wsUUID = getUuid();
				// 重连
				if (status) {
					console.log('========= 重连成功 ===========');
					store.dispatch('checkSocket', this.wsUUID)
				}
				return this.websocket;
			},
			fail: () => {
				uni.showToast({
					title: 'websoket连接失败',
					icon: 'error',
					duration: 2000,
				});
			},
		});
		this.wsOpen();
		this.wsMessage();
		this.wsOnerror();
	}

	// 重连
	reconnect() {
		if (this.reconnectObj.lock) return;
		this.reconnectObj.lock = true;
		// @ts-ignore
		clearTimeout(this.reconnectObj.timer);
		// if (this.reconnectObj.limit < this.reconnectObj.maxLimit) {
		// @ts-ignore
		this.reconnectObj.timer = setTimeout(() => {
			console.log('========= 重连中 ===========');
			this.initWebSocket(true);
			this.reconnectObj.lock = false;
		}, this.reconnectObj.timeout);
		this.reconnectObj.limit++;
		// } else {
		//   console.log('========= 重连次数超过限制，不再重连 ===========');
		// }
	}

	// 打开连接
	wsOpen() {
		if (this.websocket) {
			return new Promise((resolve, reject) => {
				try {
					this.websocket.onOpen((evt) => {
						// 开始心跳
						this.heartCheck.reset().start(this.websocket);
						resolve(evt);
					});
					this.websocket.onClose((evt) => {
						console.log('socket 断开连接');
						// 断开重连
						!this.isClose && this.reconnect();
						resolve(evt);
					});
				} catch (err) {
					reject(err);
				}
			});
		}
	}

	// 关闭连接
	wsClose(status = false) {
		if (this.websocket) {
			this.isClose = status;
			this.websocket.close();
			return new Promise((resolve, reject) => {
				try {
					this.websocket.onClose((evt) => {
						console.log('socket 连接关闭', evt);
						resolve(evt);
					});
				} catch (err) {
					reject(err);
				}
			});
		}
	}

	// 监听消息
	wsMessage(callback) {
		// 需要监听的消息路径
		if (this.websocket) {
			try {
				this.websocket.onMessage((evt) => {
					// 判断是否有 data 数据
					if (evt.data) {
						const data = evt.data;

						if (callback) {
							callback(data);
						} else {
							console.log('收到消息', data);

							// 心跳检测重置 服务端返回的消息
							if (data === 'heartbeat_recovery') {
								this.heartCheck.reset().start(this.websocket);
							}

							// 取消调理
							if (data === 'cancel_conditioning') {
								uni.reLaunch({
									url: '/pages/index/index'
								});
							}
						}
					}
				});
			} catch (err) {
				callback(err);
			}
		}
	}

	// 发送消息
	wsSend(options, isFile = false) {
		if (this.websocket) {
			try {
				if (isFile) {
					const params = {
						...options
					};
					params.RequestId = getUuid();
					this.websocket.send(params);
				} else {
					this.websocket.send(JSON.stringify(options));
				}
			} catch (e) {
				console.log('错误', e);
			}
		}
	}

	// 连接因错误而关闭时触发
	wsOnerror() {
		if (this.websocket) {
			return new Promise((resolve, reject) => {
				try {
					this.websocket.onError((evt) => {
						console.log('socket 连接错误', evt);
						// 断开重连
						this.reconnect();
						resolve(evt);
					});
				} catch (err) {
					reject(err);
				}
			});
		}
	}

	// 判断是否是json字符串
	isJsonString(str) {
		try {
			if (typeof JSON.parse(str) == 'object') {
				return true;
			}
		} catch (e) {
			console.log('isJsonString:错误捕获');
		}
		return false;
	}
}

export {
	socketClient
};